import java.awt.Color
import java.awt.Font
import java.awt.Graphics2D
import java.awt.RenderingHints
import java.awt.geom.Rectangle2D
import java.awt.image.BufferedImage
import javax.imageio.ImageIO

class CaptchaController {

  private static final String SOURCECHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

  def index = {
    response.setContentType('image/png')
    response.setHeader('Cache-control', 'no-cache')

    // Generate and remember the Source Character string (6 characters)
    int l = SOURCECHARS.length()
    StringBuilder b = new StringBuilder()
    4.times {
      int r = (int) (Math.random() * l)
      b.append(SOURCECHARS.charAt(r))
    }

    final int height = 200
    final int width = 200
    final int space = 20
    final int fontSize = 24

    System.setProperty('java.awt.headless', 'true')
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)
    Graphics2D g2d = bufferedImage.createGraphics()
    Font font = new Font('Serif', Font.BOLD, fontSize)
    g2d.setFont(font)
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
    Rectangle2D fontRect = font.getStringBounds(b.toString(), g2d.getFontRenderContext())
    // Now, create a graphic 'space' pixels wider and taller than the the font
    bufferedImage = new BufferedImage((int) fontRect.getWidth() + space,
            (int) fontRect.getHeight() ,
            BufferedImage.TYPE_INT_RGB)
    g2d = bufferedImage.createGraphics()
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
    g2d.setFont(font)

    // Draw the background
    g2d.setColor(Color.WHITE)
    g2d.fillRect(0, 0, width, height)

    // Draw the lines
    g2d.setColor(Color.GRAY)
    int x1
    int y1
    int x2
    int y2
    final int step = 10
    x1 = 0
    y1 = step
    x2 = step
    y2 = 0
    while (x1 < width || x2 < width || y1 < height || y2 < height) {
      g2d.drawLine(x1, y1, x2, y2)
      if (y1 < height) {
        x1 = 0
        y1 += step
      }
      else if (x1 < width) {
        y1 = height
        x1 += step
      }
      else {
        x1 = width
        y1 = height
      }

      if (x2 < width) {
        y2 = 0
        x2 += step
      }
      else if (y2 < height) {
        x2 = width
        y2 += step
      }
      else {
        y2 = height
        x2 = width
      }
    }

    // Draw the String
    g2d.setColor(Color.black)
//    g2d.setColor(new Color(30,110,30))

    g2d.drawString(b.toString(), (int) (space / 2), (int) fontRect.getHeight()  - (int)(fontSize /4 + 2))

    OutputStream out = response.getOutputStream()
    ImageIO.write(bufferedImage, 'PNG', out)
    out.close()

    session.setAttribute('captcha', b.toString())
  }
}
